/**
 * Choicesoft.com.cn Inc.
 * Copyright (c) 2004-2018 All Rights Reserved.
 */
package com.test.shutdown;

import java.util.concurrent.Executor;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import org.apache.catalina.connector.Connector;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.embedded.tomcat.TomcatConnectorCustomizer;
import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory;
import org.springframework.boot.web.server.WebServerFactoryCustomizer;
import org.springframework.context.ApplicationListener;
import org.springframework.context.annotation.Bean;
import org.springframework.context.event.ContextClosedEvent;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 * @author chenxubing
 * @version $Id: ShutdownApplication.java, v 0.1 2018-09-06 上午9:19 chenxubing Exp $$
 */
@RestController
@SpringBootApplication
public class ShutdownApplication {

    public static void main(String args[]) {
        SpringApplication.run(ShutdownApplication.class);
    }

    @GetMapping("/work")
    public String work() throws InterruptedException {
        System.out.println("in");
        Thread.sleep(10000);
        System.out.println("out");
        return "work";
    }

    @Bean
    public GracefulShutdown gracefulShutdown() {
        return new GracefulShutdown();
    }

    @Bean
    public WebServerFactoryCustomizer tomcatCustomizer() {
        return (container) -> {
            System.out.println("================================看下是个啥=======" + container.getClass().getCanonicalName());
            if (container instanceof TomcatServletWebServerFactory) {
                ((TomcatServletWebServerFactory) container)
                        .addConnectorCustomizers(gracefulShutdown());
            }
        };
    }

    private static class GracefulShutdown implements TomcatConnectorCustomizer,
            ApplicationListener<ContextClosedEvent> {
        private static final long TIME_OUT_SECONDS = 30;

        private volatile Connector connector;

        @Override
        public void customize(Connector connector) {
            this.connector = connector;
        }

        @Override
        public void onApplicationEvent(ContextClosedEvent event) {
            this.connector.pause();
            Executor executor = this.connector.getProtocolHandler().getExecutor();
            if (executor instanceof ThreadPoolExecutor) {
                System.out.println("准备杀死他了...");
                try {
                    ThreadPoolExecutor threadPoolExecutor = (ThreadPoolExecutor) executor;
                    threadPoolExecutor.shutdown();
                    if (!threadPoolExecutor.awaitTermination(TIME_OUT_SECONDS, TimeUnit.SECONDS)) {
                        System.out.println("30秒还没杀死...");
                    }
                } catch (InterruptedException ex) {
                    Thread.currentThread().interrupt();
                }
            }
        }

    }
}
